/*
 * 常用的JS工具函数
 *   - 判断对象是否为空；
 *   - 判断Array中是否存在空元素，只要有一个元素为空就判定这个Array是空的；
 *   - 判断是否是整数；
 *   - 把数组中的元素拼接成一个字符串；
 *   - 将元素置入数组，如果已存在就不添加，否则就置入
 *   - 判断元素是否已存于数组中
 *   - 已知Array元素的引用或副本，但未知其所在数组的索引，将它从数组中删除
 *   - 去除字符串首尾空格（兼容IE8）
 */
'use strict'

define(() => {
    return {
        /**********************************   为空判断   *********************************************/

        /**
         * 判断对象是否为空。这些都是空对象：string类型去掉首尾空格后是空字符串、undefined、null、
         * Array长度为0、json对象没有任何 属性-值 对、number类型小于等于0、boolean类型值是false
         * @param {Object} val [待判断对象]
         * @returns {boolean} true - 空对象、false - 不是空对象
         */
        isBlank(val) {
            let flag = false
            let sType = typeof val
            if ('undefined' == sType) {
                flag = true
            } else if ('object' == sType) {
                if (null == val) {
                    flag = true
                } else if (Array == val.constructor) {
                    if (!val.length) {
                        flag = true
                    }
                } else {
                    let hasLoop = false
                    for (let key in val) {
                        hasLoop = true
                        break
                    }
                    flag = !hasLoop
                }
            } else if ('string' == sType && '' == this.trim(val)) {
                flag = true
            } else if ('number' == sType && 0 >= val) {
                flag = true
            } else if ('boolean' == sType && !val) {
                flag = true
            }
            return flag
        },

        /**
         * 判断Array中是否存在空元素。空元素判断标准是：
         * string类型去掉首尾空格后是空字符串、undefined、null、Array长度为0、
         * json对象没有任何 属性-值 对、number类型小于等于0、boolean类型值是false
         * @param {Object} val [待判断对象]
         * @returns {boolean} true - 空对象、false - 不是空对象
         */
        anyBlank(list) {
            let flag = true
            if (Array == list.constructor && !this.isBlank(list)) {
                let isBlank = false
                for (let i = 0; i < list.length; i++) {
                    if (this.isBlank(list[i])) {
                        isBlank = true
                        break
                    }
                }
                flag = isBlank
            }
            return flag
        },

        /**********************************   number   *********************************************/

        /**
         * 判断是否是整数
         * @param {number|string} mun [待判断对象]
         * @returns {boolean} true - 整数、false - 不是整数
         */
        isInteger(num) {
            let flag = true
            if ('number' != typeof num && this.isBlank(num)) {
                flag = false
            } else if ('number' != typeof num && !this.isBlank(num) && -1 != num.indexOf(' ')) {
                flag = false
            } else if (isNaN(num)) {
                flag = false
            } else if (-1 != num.toString().indexOf('.')) {
                flag = false
            }
            return flag
        },

        /**********************************   Array   *********************************************/

        /**
         * 把数组中的元素拼接成一个字符串
         * ///扩展：namespace命名空间的层级带扩展，目前只能获取一级命名空间
         * @param [Array] list [待合并成字符串的数组]
         * @param [string] namespace [拼接的内容是 数组元素的namespace命名空间的值]
         * @param [string] split [拼接分隔符]
         * @returns [string] 分割后的字符串
         */
        joinString(list, namespace, split) {
            let str = ''
            if (!this.isBlank(list)) {
                if (this.isBlank(split)) {
                    split = '，'
                }
                for (let i = 0; i < list.length; i++) {
                    if (i == list.length - 1) {
                        split = ''
                    }
                    str += list[i][namespace] + split
                }
            }
            return str
        },

        /**
         * 将元素置入数组，如果已存在就不添加，否则就置入
         * ///扩展：namespace命名空间的层级带扩展，目前只能获取一级命名空间
         * @param [Object] element [待置入对象，可以是基本类型也可以是一个对象]
         * @param [Array] list [数组对象]
         * @param [string] namespace [如果待置入对象是对象类型，可以以namespace命名空间的值作为判断是否存在的依据]
         */
        putSingly(element, list, namespace) {
            let hasElement = false
            let _element
            if (!this.isBlank(namespace)) {
                _element = element[namespace]
            } else {
                _element = element
            }
            for (let i = 0, len = list.length; i < len; i++) {
                let curEle = list[i]
                if (!this.isBlank(namespace)) {
                    curEle = curEle[namespace]
                }
                if (curEle == _element) {
                    hasElement = true
                    break
                }
            }
            !hasElement && list.push(element)
        },

        /**
         * 判断元素是否已存于数组中
         * ///扩展：namespace命名空间的层级带扩展，目前只能获取一级命名空间
         * @param [Object] element [待置入对象，可以是基本类型也可以是一个对象]
         * @param [Array] list [数组对象]
         * @param [string] namespace [如果待置入对象是对象类型，可以以namespace命名空间的值作为判断是否存在的依据]
         * @returns [number] 返回值等于 -1 表示数组中没有此元素，大于等于 0 的返回值是元素所在数组的索引
         */
        hasElement(element, list, namespace) {
            let index = -1
            let _element
            if (!this.isBlank(namespace)) {
                _element = element[namespace]
            } else {
                _element = element
            }
            for (let i = 0, len = list.length; i < len; i++) {
                let curEle = list[i]
                if (!this.isBlank(namespace)) {
                    curEle = curEle[namespace]
                }
                if (curEle == _element) {
                    index = i
                    break
                }
            }
            return index
        },

        /**
         * 已知Array元素的引用或副本，但未知其所在数组的索引，将它从数组中删除
         * ///扩展：namespace命名空间的层级带扩展，目前只能获取一级命名空间
         * @param [Object] element [待删除对象，可以是基本类型也可以是一个对象]
         * @param [Array] list [数组对象]
         * @param [string] namespace [如果待删除对象是对象类型，可以以namespace命名空间的值作为判断是否存在的依据]
         * @returns [number] 返回值等于 -1 表示数组中没有此元素，大于等于 0 的返回值是待删除元素所在数组的索引
         */
        removeArrayEle(element, list, namespace) {
            let index = -1
            let _element
            if (!this.isBlank(namespace)) {
                _element = element[namespace]
            } else {
                _element = element
            }
            for (let i = 0, len = list.length; i < len; i++) {
                let curEle = list[i]
                if (!this.isBlank(namespace)) {
                    curEle = curEle[namespace]
                }
                if (curEle == _element) {
                    list.splice(i, 1)
                    index = i
                    break
                }
            }
            return index
        },

        /**
         * 去除字符串首尾空格（兼容IE8）
         * @param [string] str [待去除字符串]
         * @returns [string] 去除后的字符串
         */
        trim(str) {
            return str.replace(/(^\s*)|(\s*$)/g, "");
        },

        /**
         * Ajax请求
         * @param [string] str [待去除字符串]
         * @returns [string] 去除后的字符串
         */
        reqAjax(url, params, succCallback, type, async) {
            if (this.isBlank(params)) {
                params = {}
            }
            if (this.isBlank(type)) {
                async = 'get'
            }
            if (this.isBlank(async)) {
                type = 'true'
            }
            if (this.isBlank(succCallback)) {
                succCallback = null
            }
            $.ajax({
                url: url, // 接口地址
                data: params, // 请求入参
                type: type, // post/get
                dataType: 'text', // 响应格式，如：json、text等
                async: async, // 同步/异步
                timeout : 20000,
                success : succCallback,
                error: null,
                beforeSend: null // 调用ajax请求前处理的方法
            })
        }
    }
})